package org.scratchcrew.web.cometd;

import org.cometd.Client;
import org.cometd.Message;
import org.cometd.SecurityPolicy;
import org.scratchcrew.services.SecurityService;
import org.scratchcrew.web.cometd.handlers.BoardChannelSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

public class BoardPolicy implements SecurityPolicy {
	protected final Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	protected SecurityService securityService;

	@Autowired
	protected SpringContinuationBayeux bayeux;

	@Autowired
	protected BoardChannelSupport boardChannelSupport;

	public void setSecurityService(SecurityService securityService) {
		this.securityService = securityService;
	}

	public void setBayeux(SpringContinuationBayeux bayeux) {
		this.bayeux = bayeux;
	}

	public void setBoardChannelSupport(BoardChannelSupport boardChannelSupport) {
		this.boardChannelSupport = boardChannelSupport;
	}

	/**
	 * All permissions are transformed to one - allow or deny
	 * 
	 * @param client
	 * @return
	 */
	protected boolean allowUser(final Client client, final String channel) {
		if (!boardChannelSupport.isBoardChannel(channel)) {
			// not for board policy
			return true;
		}

		String userName = null;
		if (client != null) {
			userName = bayeux.getUserNameByClientId(client.getId());
		}

		final Long boardId = boardChannelSupport.getBoardIdByChannel(channel);
		return securityService.allowUserForBoard(userName, boardId);
	}

	@Override
	public boolean canCreate(Client client, String channel, Message message) {
		return allowUser(client, channel);
	}

	@Override
	public boolean canHandshake(Message message) {
		return true;
	}

	@Override
	public boolean canPublish(Client client, String channel, Message messsage) {
		return allowUser(client, channel);
	}

	@Override
	public boolean canSubscribe(Client client, String channel, Message messsage) {
		return allowUser(client, channel);
	}
}
